#include "jobtest.h"

/*Registry this TestSuite to theTestFactoryRegistry*/
CPPUNIT_TEST_SUITE_REGISTRATION (JobTest);

void JobTest::setUp() {
	SG_init();
	job1 = new Job("job1", 100, 1);
	job2 = new Job("job2", 100, 1);	
}

void JobTest::testAddTask() { fprintf(stderr,">>> JobTest::testAddTask()\n");
	Task *t1=NULL, *t2=NULL, *t3=NULL;

	CPPUNIT_ASSERT(job1->getNumberOfTasks()==0);
	
	job1->addTask(5000,0);
	job1->addTask(6000,0);
	job1->addTask(7000,0);	
	
	CPPUNIT_ASSERT(job1->getNumberOfTasks()==3);
	
	t1 = job1->getTaskByIndex(0);
	t2 = job1->getTaskByIndex(1);
	t3 = job1->getTaskByIndex(2);	
	
	
	CPPUNIT_ASSERT_MESSAGE("Task name should be task_1", (!strcmp("task_1", t1->getName())));		
	CPPUNIT_ASSERT_MESSAGE("Task name shoudl be task_2", (!strcmp("task_2", t2->getName())));
	CPPUNIT_ASSERT_MESSAGE("Task name shoudl be task_3", (!strcmp("task_3", t3->getName())));	
	
}


void JobTest::testReplicate() { fprintf(stderr,">>> JobTest::testReplicate()\n");
	job2->addTask(5000,0);
	job2->addTask(6000,0);
	job2->addTask(7000,0);		

	Task *t1 = job2->getTaskByIndex(0);

	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 0 replica", 0, t1->getNumberOfReplicas());			
	job2->createReplicaOfTask(0, 0);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 1 replica", 1, t1->getNumberOfReplicas());				
	job2->createReplicaOfTask(0, 0); 
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 2 replicas", 2, t1->getNumberOfReplicas());		
	
	//Other tasks should have no replcias
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 0 replica", 0, job2->getTaskByIndex(1)->getNumberOfReplicas());		
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 0 replica", 0, job2->getTaskByIndex(2)->getNumberOfReplicas());			
	
	//Get the fields of replcias of task t1 (first task added to the job2)
	t1 = job2->getTaskByIndex(0);
	for (int n=0; n < t1->getNumberOfReplicas(); n++) {
		char *replicaName = new char[64];		
		SG_Task replicaOfTask_1 = t1->getComputationReplicaByIndex(n);
		SG_Task transferInReplica = t1->getTransferReplicaByIndex(n, Task::IN);		
		SG_Task transferOutReplica = t1->getTransferReplicaByIndex(n, Task::OUT);				
		sprintf(replicaName, "%s_%d", t1->getName(),(n+1));
		CPPUNIT_ASSERT_MESSAGE("Replica Name should be the taskname_n",(!strcmp(replicaName,SG_getTaskName(replicaOfTask_1))));
		CPPUNIT_ASSERT_MESSAGE("Replica CompCost should be the task cost",t1->getComputationCost() ==SG_getTaskCost(replicaOfTask_1));		
		CPPUNIT_ASSERT_MESSAGE("Replica inputTransferCost should be 0",0 ==SG_getTaskCost(transferInReplica));
		CPPUNIT_ASSERT_MESSAGE("Replica outputTransferCost should be 0",0 ==SG_getTaskCost(transferOutReplica));		
	}

}

void JobTest::testResetTasks() { fprintf(stderr,">>> JobTest::testResetTasks()\n");
	job1->addTask(5000,0);
	job1->addTask(6000,0);
	job1->addTask(7000,0);	

	job1->resetTasks();
	
	Task *t1 = job1->getTaskByIndex(0);
	
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 0 replica", 0, t1->getNumberOfReplicas());			
	job1->createReplicaOfTask(0, 0);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 1 replica", 1, t1->getNumberOfReplicas());				
	job1->createReplicaOfTask(0, 0); 
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 2 replicas", 2, t1->getNumberOfReplicas());		
	job1->resetTasks();
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Task should have 0 replica", 0, t1->getNumberOfReplicas());			
	
}

void JobTest::testGetTaskByName() { fprintf(stderr,">>> JobTest::testGetTaskByName()\n");
	job1->addTask(5000,0);
	job1->addTask(6000,0);
	job1->addTask(7000,0);		

	CPPUNIT_ASSERT(!strcmp("task_1",job1->getTaskByName("task_1")->getName()));
	
	job1->getTaskByName("task_2");
	
	job1->getTaskByName("task_3");
	
	try {
		job1->getTaskByName("fakeTask");			
		CPPUNIT_FAIL("An exception should be throwed!");
	} catch (std::runtime_error &e){
		//Pass
	}

}

void JobTest::tearDown() {
	delete job1;
	delete job2;
	SG_clear();
}

